///*
//@Time : 2021/1/22 3:43 下午
//@Author : chenle
//@File : database2
//@Software: GoLand
//*/
package lego

//
//import (
//	"database/sql"
//	"database/sql/driver"
//	"encoding/json"
//	"errors"
//	"fmt"
//	"gorm.io/gorm/clause"
//	"log"
//	"reflect"
//	"time"
//
//	"gorm.io/driver/mysql"
//	"gorm.io/gorm"
//	glog "gorm.io/gorm/logger"
//	"gorm.io/gorm/schema"
//)
//
//type Model2 struct {
//	ID        uint    `gorm:"primary_key" json:"id"`
//	CreatedAt string  `gorm:"type:varchar(30);default:null" json:"created_at"`
//	UpdatedAt string  `gorm:"type:varchar(30);default:null" json:"updated_at"`
//	DeletedAt Deleted `gorm:"default:null" json:"deleted_at"`
//}
//
////func MysqlSetup() {
////	var err error
////
////	dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local", username, password, host, port, dbname)
////
////	globalDB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
////		NamingStrategy: schema.NamingStrategy{
////			TablePrefix:   "t_",
////			SingularTable: true,
////		},
////		Logger: glog.Default.LogMode(glog.Info),
////	})
////	if err != nil {
////		log.Fatalln("mysql open error:", err)
////	}
////
////	globalDB.Callback().Create().Before("gorm:create").Register("gorm:update_time_stamp", updateTimeStampForCreateCallback2)
////	globalDB.Callback().Update().Before("gorm:update").Register("gorm:update_time_stamp", updateTimeStampForUpdateCallback2)
////
////	globalDB.AutoMigrate(
////		&Product{},
////		&Project{},
////	)
////}
//
//func GetDB2() *gorm.DB {
//	return db2
//}
//
//func updateTimeStampForCreateCallback2(db *gorm.DB) {
//	if db.Statement.Schema != nil {
//		currentTime := getCurrentTime()
//		fmt.Println("[CreateCallback] current time:", currentTime)
//		SetSchemaFieldValue(db, "CreatedAt", currentTime)
//		SetSchemaFieldValue(db, "UpdatedAt", currentTime)
//	}
//}
//
//func updateTimeStampForUpdateCallback2(db *gorm.DB) {
//	// if _, ok := db.Statement.Settings.Load("gorm:update_time_stamp"); ok {
//	if db.Statement.Schema != nil {
//		currentTime := getCurrentTime()
//		fmt.Println("[UpdateCallback] current time:", currentTime)
//		db.Statement.SetColumn("UpdatedAt", currentTime)
//		db.Statement.AddClause(clause.Where{
//			Exprs: []clause.Expression{clause.Eq{Column: "deleted_at"}},
//		})
//	}
//}
//
//func SetSchemaFieldValue(db *gorm.DB, fieldName string, value interface{}) error {
//	field := db.Statement.Schema.LookUpField(fieldName)
//	fmt.Println("[SetSchemaFieldValue] fieldName ", fieldName, ", filed:", field)
//	if field == nil {
//		return errors.New("can't find the field")
//	}
//	err := field.Set(db.Statement.ReflectValue, value)
//	if err != nil {
//		log.Println("schema field set err:", err)
//		return err
//	}
//
//	return nil
//}
//
//func getCurrentTime() string {
//	return time.Now().Format("2006-01-02 15:04:05")
//}
//
//var db2 *gorm.DB
//var err error
//
//// 初始化 gorm2.0
//func (l *Lego) initDatabase2_0(values ...interface{}) {
//	SysInfo(">>>>>>>> |db model gorm2.0 is initing")
//	dbConf := confValue.GetMysqlConf()
//	dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
//		dbConf.Username,
//		dbConf.Password,
//		dbConf.Address,
//		dbConf.DbName)
//	/*newLogger := logger.New(
//		log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
//		logger.Config{
//			SlowThreshold: time.Second,   // 慢 SQL 阈值
//			LogLevel:      logger.Silent, // Log level
//			Colorful:      false,         // 禁用彩色打印
//		},
//	)
//	newLogger.LogMode(logger.Silent)*/
//	db2, err = gorm.Open(mysql.New(mysql.Config{
//		DSN:                       dsn,   // DSN data source name
//		DefaultStringSize:         256,   // string 类型字段的默认长度
//		DisableDatetimePrecision:  true,  // 禁用 datetime 精度，MySQL 5.6 之前的数据库不支持
//		DontSupportRenameIndex:    true,  // 重命名索引时采用删除并新建的方式，MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
//		DontSupportRenameColumn:   true,  // 用 `change` 重命名列，MySQL 8 之前的数据库和 MariaDB 不支持重命名列
//		SkipInitializeWithVersion: false, // 根据版本自动配置
//	}), &gorm.Config{
//		//SkipDefaultTransaction: true,为了确保数据一致性，GORM 会在事务里执行写入操作（创建、更新、删除）。如果没有这方面的要求，您可以在初始化时禁用它。
//		NamingStrategy: schema.NamingStrategy{ //GORM 允许用户通过覆盖默认的命名策略更改默认的命名约定，这需要实现接口 Namer
//			TablePrefix:   "t_", // 表名前缀，`User` 的表名应该是 `t_users`
//			SingularTable: true, // 使用单数表名，启用该选项，此时，`User` 的表名应该是 `t_user`
//		},
//		Logger: glog.Default.LogMode(glog.Info), //允许通过覆盖此选项更改 GORM 的默认 logger
//	})
//	if err != nil {
//		panic(err)
//	}
//	sqlDB, err := db2.DB()
//	if err != nil {
//		panic(err)
//	}
//
//	// SetMaxIdleConns 设置空闲连接池中连接的最大数量
//	sqlDB.SetMaxIdleConns(dbConf.MaxIdleConns)
//	// SetMaxOpenConns 设置打开数据库连接的最大数量
//	sqlDB.SetMaxOpenConns(dbConf.MaxOpenConns)
//	// SetConnMaxLifetime 设置了连接可复用的最大时间
//	sqlDB.SetConnMaxLifetime(time.Duration(dbConf.ConnMaxLifetime * int64(time.Millisecond)))
//	//db.Callback().Create().Replace("gorm:update_time_stamp", updateTimeStampForCreateCallback)
//	db2.Callback().Create().Before("gorm:create").Register("gorm:update_time_stamp", updateTimeStampForCreateCallback2)
//	db2.Callback().Update().Before("gorm:update").Register("gorm:update_time_stamp", updateTimeStampForUpdateCallback2)
//	db2.AutoMigrate(values...)
//
//	l.Engine.DB2 = db2
//
//	SysInfo("<<<<<<<< |db model gorm2 init success")
//}
//
//type Deleted sql.NullString
//
//// Scan implements the Scanner interface.
//func (n *Deleted) Scan(value interface{}) error {
//	return (*sql.NullString)(n).Scan(value)
//}
//
//// Value implements the driver Valuer interface.
//func (n Deleted) Value() (driver.Value, error) {
//	if !n.Valid {
//		return nil, nil
//	}
//	return n.String, nil
//}
//
//func (n Deleted) MarshalJSON() ([]byte, error) {
//	return json.Marshal(n.String)
//}
//
//func (n *Deleted) UnmarshalJSON(b []byte) error {
//	err := json.Unmarshal(b, &n.String)
//	if err == nil {
//		n.Valid = true
//	}
//	return err
//}
//
//func (Deleted) QueryClauses(f *schema.Field) []clause.Interface {
//	return []clause.Interface{SoftDeleteQueryClause{Field: f}}
//}
//
//type SoftDeleteQueryClause struct {
//	Field *schema.Field
//}
//
//func (sd SoftDeleteQueryClause) Name() string {
//	return ""
//}
//
//func (sd SoftDeleteQueryClause) Build(clause.Builder) {
//}
//
//func (sd SoftDeleteQueryClause) MergeClause(*clause.Clause) {
//}
//
//func (sd SoftDeleteQueryClause) ModifyStatement(stmt *gorm.Statement) {
//	if _, ok := stmt.Clauses["soft_delete_enabled"]; !ok {
//		if c, ok := stmt.Clauses["WHERE"]; ok {
//			if where, ok := c.Expression.(clause.Where); ok && len(where.Exprs) > 1 {
//				for _, expr := range where.Exprs {
//					if orCond, ok := expr.(clause.OrConditions); ok && len(orCond.Exprs) == 1 {
//						where.Exprs = []clause.Expression{clause.And(where.Exprs...)}
//						c.Expression = where
//						stmt.Clauses["WHERE"] = c
//						break
//					}
//				}
//			}
//		}
//
//		stmt.AddClause(clause.Where{Exprs: []clause.Expression{
//			clause.Eq{Column: clause.Column{Table: clause.CurrentTable, Name: sd.Field.DBName}, Value: nil},
//		}})
//		stmt.Clauses["soft_delete_enabled"] = clause.Clause{}
//	}
//}
//
//func (Deleted) DeleteClauses(f *schema.Field) []clause.Interface {
//	return []clause.Interface{SoftDeleteDeleteClause{Field: f}}
//}
//
//type SoftDeleteDeleteClause struct {
//	Field *schema.Field
//}
//
//func (sd SoftDeleteDeleteClause) Name() string {
//	return ""
//}
//
//func (sd SoftDeleteDeleteClause) Build(clause.Builder) {
//}
//
//func (sd SoftDeleteDeleteClause) MergeClause(*clause.Clause) {
//}
//
//func (sd SoftDeleteDeleteClause) ModifyStatement(stmt *gorm.Statement) {
//	if stmt.SQL.String() == "" {
//		stmt.AddClause(clause.Set{{Column: clause.Column{Name: sd.Field.DBName}, Value: stmt.DB.NowFunc()}})
//
//		if stmt.Schema != nil {
//			_, queryValues := schema.GetIdentityFieldValuesMap(stmt.ReflectValue, stmt.Schema.PrimaryFields)
//			column, values := schema.ToQueryValues(stmt.Table, stmt.Schema.PrimaryFieldDBNames, queryValues)
//
//			if len(values) > 0 {
//				stmt.AddClause(clause.Where{Exprs: []clause.Expression{clause.IN{Column: column, Values: values}}})
//			}
//
//			if stmt.ReflectValue.CanAddr() && stmt.Dest != stmt.Model && stmt.Model != nil {
//				_, queryValues = schema.GetIdentityFieldValuesMap(reflect.ValueOf(stmt.Model), stmt.Schema.PrimaryFields)
//				column, values = schema.ToQueryValues(stmt.Table, stmt.Schema.PrimaryFieldDBNames, queryValues)
//
//				if len(values) > 0 {
//					stmt.AddClause(clause.Where{Exprs: []clause.Expression{clause.IN{Column: column, Values: values}}})
//				}
//			}
//		}
//
//		stmt.AddClauseIfNotExists(clause.Update{})
//		stmt.Build("UPDATE", "SET", "WHERE")
//	}
//}
//
//
